package com.ruoyi.vehicle.entity;

import com.ruoyi.vehicle.entity.request.RegisterMsg;
import com.ruoyi.vehicle.entity.response.CommonMsgRespBody;
import com.ruoyi.vehicle.entity.response.RegisterMsgRespBody;
import com.ruoyi.vehicle.utils.BitOperator;
import com.ruoyi.vehicle.utils.Constants;
import com.ruoyi.vehicle.utils.JT808ProtocolUtils;

import java.util.Arrays;

/**
 * @author : CZQ
 * @date : 2024-09-17 15:00
 * @description :
 **/
public class MsgEncoder {

    private BitOperator bitOperator;
    private JT808ProtocolUtils jt808ProtocolUtils;

    public MsgEncoder() {
        this.bitOperator = new BitOperator();
        this.jt808ProtocolUtils = new JT808ProtocolUtils();
    }

    public byte[] encodeRegisterResp(RegisterMsg req, RegisterMsgRespBody respMsgBody, int flowId) throws Exception {
        // 消息体字节数组
        byte[] msgBody = null;
        // 鉴权码(STRING) 只有在成功后才有该字段
        if (respMsgBody.getReplyCode() == RegisterMsgRespBody.success) {
            msgBody = this.bitOperator.concatAll(Arrays.asList(//
                    bitOperator.integerTo2Bytes(respMsgBody.getReplyFlowId()), // 流水号(2)
                    new byte[] { respMsgBody.getReplyCode() }, // 结果
                    respMsgBody.getReplyToken().getBytes(Constants.gbk_charset)// 鉴权码(STRING)
            ));
        } else {
            msgBody = this.bitOperator.concatAll(Arrays.asList(//
                    bitOperator.integerTo2Bytes(respMsgBody.getReplyFlowId()), // 流水号(2)
                    new byte[] { respMsgBody.getReplyCode() }// 错误代码
            ));
        }

        // 消息头
        int msgBodyProps = this.jt808ProtocolUtils.generateMsgBodyProps(msgBody.length, 0b000, false, 1);
        byte[] msgHeader = this.jt808ProtocolUtils.generateMsgHeader(req.getMsgHeader().getTerminalPhone(),
                Constants.cmd_terminal_register_resp, msgBody, msgBodyProps, flowId, req.getMsgHeader().getVersion());
        byte[] headerAndBody = this.bitOperator.concatAll(msgHeader, msgBody);

        // 校验码
        int checkSum = this.bitOperator.getCheckSum4JT808(headerAndBody, 0, headerAndBody.length);
        // 连接并且转义
        return this.doEncode(headerAndBody, checkSum);
    }

    private byte[] doEncode(byte[] headerAndBody, int checkSum) throws Exception {
        byte[] noEscapedBytes = this.bitOperator.concatAll(Arrays.asList(//
                new byte[] { Constants.pkg_delimiter }, // 0x7e
                headerAndBody, // 消息头+ 消息体
                bitOperator.integerTo1Bytes(checkSum), // 校验码
                new byte[] { Constants.pkg_delimiter }// 0x7e
        ));
        // 转义
        return jt808ProtocolUtils.doEscape4Send(noEscapedBytes, 1, noEscapedBytes.length - 2);
    }

    public byte[] encodeCommmonResp(PackageData req, CommonMsgRespBody respMsgBody, int flowId) throws Exception {
        // 消息体字节数组
        byte[] msgBody = this.bitOperator.concatAll(Arrays.asList(//
                bitOperator.integerTo2Bytes(respMsgBody.getReplyFlowId()), // 流水号(2)
                bitOperator.integerTo2Bytes(respMsgBody.getReplyId()),  //应答ID
                bitOperator.integerTo1Bytes(respMsgBody.getReplyCode())// 结果
                //new byte[] { respMsgBody.getReplyCode() }
        ));


        // 消息头
        // 生成消息体属性
        int msgBodyProps = this.jt808ProtocolUtils.generateMsgBodyProps(msgBody.length, 0b000, false, 1);
        byte[] msgHeader = this.jt808ProtocolUtils.generateMsgHeader(req.getMsgHeader().getTerminalPhone(),
                Constants.cmd_common_resp, msgBody, msgBodyProps, flowId, req.getMsgHeader().getVersion());
        byte[] headerAndBody = this.bitOperator.concatAll(msgHeader, msgBody);

        // 校验码
        int checkSum = this.bitOperator.getCheckSum4JT808(headerAndBody, 0, headerAndBody.length);
        // 连接并且转义
        return this.doEncode(headerAndBody, checkSum);
    }
}
